package com.model.demo.designmodel.observer.event.core;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

//监听器，它就是观察者
public class EventLisenter {

    //JDK底层的Lisenter通常也是这样来设计的
    private Map<String, Event> eventMap=new HashMap();

    //存放触发的事件类型，事件对象（目标对象)(这个事件触发，要通知谁，根据事件类型做动作)
    public void addLisenter(String eventType, Object target){

        try {
            this.addLisenter(
                    eventType,
                    target,
                    target.getClass().getMethod("on" + toUpperFirstCase(eventType),Event.class));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }
    //存放触发的事件类型，事件对象（目标对象，回调）(这个事件触发，要通知谁，要做什么动作)
    public void addLisenter(String eventType, Object target, Method callback){
        //注册事件
        eventMap.put(eventType , new Event(target, callback));
    }

    //触发，只要有动作就触发
    public void trigger(Event event){
        event.setSource(this);
        event.setTime(System.currentTimeMillis());
            try {
                //回调 目标对象（观察者）必须要有回调函数
                if(event.getCallback() != null) {
                    event.getCallback().invoke(event.getTarget(), event);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
    }
    //事件名称触发
    public void trigger(String trigger){
        if(!eventMap.containsKey(trigger)){
            return;
        }
        trigger(eventMap.get(trigger).setTrigger(trigger));
    }

    //逻辑处理的私有方法，首字母大写
    private String toUpperFirstCase(String str){
        char[] chars = str.toCharArray();
        chars[0] -= 32;
        return String.valueOf(chars);
    }
}
